package me.atbar.moonlib.area.type;

import lombok.Getter;
import me.atbar.moonlib.area.BaseArea;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 */
public class PurtmarsArea extends BaseArea implements ConfigurationSerializable {

    @Getter
    private final Location min;
    @Getter
    private final Location max;
    @Getter
    private final Player player;
    @Getter
    private final String name;
    @Getter
    private final ItemStack areaCore;

    private PurtmarsArea(PurtmarsAreaBuilder builder) {
        super(builder);
        this.min = builder.getMin();
        this.max = builder.getMax();
        this.player = builder.getPlayer();
        this.areaCore = builder.getAreaCore();
        this.name = builder.getName();
    }

    @Override
    public Map<String, Object> serialize() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", name);
        return map;
    }

    public PurtmarsArea deserializ(Map<String, Object> args) {
        return null;
    }

    public static class PurtmarsAreaBuilder extends BaseBuilder<PurtmarsAreaBuilder> {

        @Getter
        private final Location min;
        @Getter
        private final Location max;
        @Getter
        private final Player player;
        @Getter
        private String name;
        @Getter
        private ItemStack areaCore;

        public PurtmarsAreaBuilder(Player player, Location min, Location max) {
            super(min, max);
            this.min = super.getMin();
            this.max = super.getMax();
            this.player = player;
        }

        public PurtmarsAreaBuilder name(String name) {
            this.name = name;
            return self();
        }

        public PurtmarsAreaBuilder core(ItemStack areaCore) {
            this.areaCore = areaCore;
            return self();
        }

        public PurtmarsAreaBuilder openBorder(Particle particle) {
            display(min, max, particle);
            return self();
        }

        public static void display(Location pos1, Location pos2, Particle particle) {
            for (Location location : getLocations(pos1, pos2)) {
                location.getWorld().spawnParticle(particle, location, 1);
            }
        }

        public static List<Location> getLocations(Location pos1, Location pos2) {
            // Create Ret
            List<Location> ret = new ArrayList<>();
            final World world = pos1.getWorld();
            final int xmin = pos1.getBlockX();
            final int xmax = pos2.getBlockX();
            final int ymin = pos1.getBlockY();
            final int ymax = pos2.getBlockY();
            final int zmin = pos1.getBlockZ();
            final int zmax = pos2.getBlockZ();
            int x = xmin;
            int y = ymin;
            int z = zmin;

            // Add #1
            while (x + 1 <= xmax) {
                x++;
                ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
            }

            // Add #2
            while (z + 1 <= zmax) {
                z++;
                ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
            }

            // Add #3
            while (x - 1 >= xmin) {
                x--;
                ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
            }

            // Add #4
            while (z - 1 >= zmin) {
                z--;
                ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
            }

            // Add #5
            while (y + 1 <= ymax) {
                y++;
                ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
            }

            // Add #6
            while (y - 1 >= ymin) {
                y--;
                ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
            }

            // Return Ret
            return ret;
        }

        @Override
        public PurtmarsArea build() {
            return new PurtmarsArea(this);
        }

        @Override
        protected PurtmarsAreaBuilder self() {
            return this;
        }

    }

}
